package boot;

import java.io.IOException;
import java.util.Hashtable;
import java.util.Timer;
import java.util.TimerTask;

import javax.microedition.lcdui.Canvas;
import javax.microedition.lcdui.Display;
import javax.microedition.lcdui.Displayable;
import javax.microedition.media.Manager;
import javax.microedition.media.MediaException;
import javax.microedition.media.Player;
import javax.microedition.media.PlayerListener;
import javax.microedition.media.control.MetaDataControl;
import javax.microedition.midlet.MIDlet;
import javax.microedition.midlet.MIDletStateChangeException;

import player.MP3Metadata;
import state.State;
import tool.FileConnectionUtils;
import tool.KeyCode;
import tool.Log;
import tool.MyRandom;
import tool.PlayerUtils;
import tool.RamPerfo;
import tool.TimePerfo;

import com.nokia.mid.impl.isa.ui.DeviceControl;

import db.Mp3DBRecord;
import files.Files;
import function.EmptyNavigatorException;
import function.Mp3File;
import function.Navigator;
import function.now.NowManager;
import function.playlist.DBPlaylist;
import function.playlist.NowPlaylist;
import function.playlist.SimplePlaylist;
import graphics.screens.AlertScreen;
import graphics.screens.DeleteNewScreen;
import graphics.screens.DeleteReportScreen;
import graphics.screens.EvaluationScreen;
import graphics.screens.GenresSuggestionsScreen;
import graphics.screens.LockScreen;
import graphics.screens.MainScreen;
import graphics.screens.Mp3ListScreen;
import graphics.screens.PawnScreen;
import graphics.screens.PopUpNameScreen;
import graphics.screens.ShakerScreen;
import graphics.screens.StatsScreen;
import graphics.screens.SuggestScreen;
import graphics.screens.mode.OptionScreen1;
import graphics.screens.search.ArtistSearchScreen;
import graphics.screens.search.TitleSearchScreen;

public class Boot extends MIDlet implements PlayerListener {

	public static final int HIP_HOP_CODE = -200;
	public static final int GOOD_MODE = -201;

	public static final String[] GENRES = new String[] { Genres.CALME,
			Genres.GOOD, Genres.ENERGIE, Genres.HIP_HOP, Genres.POUBELLE,
			Genres.NEW };

	private static Boot instance;

	private State state = null;

	private Player player;
	private Navigator navigator;
	private MainScreen mainScreen;
	private ArtistSearchScreen artistSearchScreen;
	private Mp3ListScreen newListScreen;
	// private PopUpPlaylistModeScreen playslistScreen = null;

	private Hashtable alreadyPlayed = new Hashtable();

	/*
	 * dir <String> |- playlist <Playlist>
	 */
	private Hashtable playlists;

	private SimplePlaylist currentPlaylist;

	private int nightModeIndex;

	private Timer pauseTimer = null;
	private Timer stopTimer = null;

	private RestartManager restartManager = null;
	private Timer restartTimer = null;
	private long currentTime = -1;

	private NowPlaylist nowPlaylist;
	private SuggestScreen suggestScreen;
	private Displayable getBackScreen;
	private GenresSuggestionsScreen genreSuggestionScreen;

	public Boot() {

		state = State.IDLE;
		state.add(State.NO_REPEAT_NO_PLAYLIST);

		RamPerfo.startMeasure();
		TimePerfo.startMeasure();

		if (instance == null) {
			instance = this;
		}
		DeviceControl.setLights(0, 100);
		state.add(State.MODE_SEARCH_BY_TITLE);
	}

	public static void createNewSuggestScreen() {
		String dbPropertiesPath = Files.BOOT_ROOT
				+ "/DBProperties/NoPoubelle.db.properties";
		String dbPath = Files.BOOT_ROOT + "/NoPoubelle.db";

		if (Boot.state().equals(State.WICKED_KEY_PRESSED)) {
			dbPropertiesPath = Files.BOOT_ROOT
					+ "/DBProperties/Boot.db.properties";
			dbPath = Files.BOOT_ROOT + "/Boot.db";
		}

		instance.suggestScreen = new SuggestScreen(dbPath, dbPropertiesPath);

	}

	private void setupNewListScreen() {
		// String newDirPath = Path.NOW;
		// FileConnection connection;
		// int count = 0;
		// Enumeration mp3s = null;
		//
		// try {
		// connection = (FileConnection) Connector.open(newDirPath);
		// mp3s = connection.list("*.link", true);
		// count = EnumerationUtils.getCount(mp3s);
		// mp3s = connection.list("*.link", true);
		// connection.close();
		// } catch (IOException e) {
		// alert(e);
		// }
		//
		// Mp3File[] newMp3s = new Mp3File[count];
		// int index = 0;
		//
		// while (mp3s.hasMoreElements()) {
		// String mp3 = (String) mp3s.nextElement();
		// Mp3File mp3File = new Mp3File(newDirPath, mp3);
		// newMp3s[index++] = mp3File;
		// }
		// newListScreen = new Mp3ListScreen(newMp3s);
	}

	private void setupPlaylists() {
		playlists = new Hashtable();
		for (int i = 0; i < GENRES.length; i++) {
			String genre = GENRES[i];
			if (Genres.NEW.equals(genre)) {
				nowPlaylist = new NowPlaylist(genre);
			} else {
				playlists.put(genre, new DBPlaylist(genre));
			}
		}
	}

	protected void destroyApp(boolean arg0) throws MIDletStateChangeException {
		try {
			if (player != null) {
				player.stop();
			}
			player = null;
		} catch (Throwable t) {
			alertException(t, this, "destroyApp()");
		}
	}

	protected void pauseApp() {

	}

	protected void startApp() throws MIDletStateChangeException {
		if (!FileConnectionUtils.isSDcardPresent()) {
			alertException(new Exception("Please insert SD card"), this, "startApp()");
			new Timer().schedule(new TimerTask() {

				public void run() {
					notifyDestroyed();
				}
			}, 3000);
			return;
		}
		addMeasure("After startApp()");
		try {
			restartManager = new RestartManager(this);
			setupDisplay();
			wrappedStart();

		} catch (Throwable t) {
			alertException(t, this, "startApp");
		}		
	}

	private void setupDisplay() throws Throwable {
		mainScreen = new MainScreen();
		artistSearchScreen = new ArtistSearchScreen();
		state.add(State.ARTIST_SEARCH_ENGAGED);
		// PopUpPlaylistModeScreen playslistScreen = new
		// PopUpPlaylistModeScreen();
		setDisplay(mainScreen);
	}

	public void readyToSetup() {
		setDisplay(mainScreen);
	}

	private void wrappedStart() throws Throwable {

		setupNewListScreen();
		addMeasure("After setupNewList()");
		setupPlaylists();
		addMeasure("After setupPlaylist()");
		addState(State.PLAYLISTS_READY);

		// TODO TEMP Disable new suggest screen at start
		 Boot.createNewSuggestScreen();
	}

	public static void addMeasure(String title) {
		RamPerfo.addMeasure(title);
		TimePerfo.addMeasure(title);
	}

	private Mp3File getRandomMP3() {

		String genre = null;
		int playlistIndex = -1;

		if (state.equals(State.ANY_MODE)) {
			if (state.equals(State.WICKED_KEY_PRESSED)) {
				playlistIndex = MyRandom.getRandomNumber(GENRES.length - 2);
			} else {
				playlistIndex = MyRandom.getRandomNumber(GENRES.length - 3);
			}
			genre = GENRES[playlistIndex];
			currentPlaylist = (SimplePlaylist) playlists.get(genre);
		} else if (currentPlaylist == null) {
			currentPlaylist = (SimplePlaylist) playlists.get(Genres.GOOD);
			// mainScreen.alert("Default playlist", 1000);
		}

		Mp3File mp3 = null;

		while (mp3 == null) {
			int mp3Index = MyRandom.getRandomNumber(currentPlaylist.getSize());
			mp3 = currentPlaylist.getMp3(mp3Index);
			String title = mp3.getTitle();
			if (alreadyPlayed.containsKey(title)) {
				mp3 = null;
			} else {
				alreadyPlayed.put(title, title);
			}
		}
		return mp3;
	}

	private void runMP3(Mp3File mp3) throws MediaException, IOException {
		if (mp3 == null) {
			return;
		}

		String rawTitle = mp3.getFilename();
		String currentMp3Title = rawTitle.substring(0, rawTitle.length() - 4);
//		Log.log("Play:\n" + currentMp3Title);
		mainScreen.repaint();

		if (player != null) {
			destroyPlayer();
		}
		// player = Manager.createPlayer(mp3.getDir() + '/' + rawTitle);
		player = Manager.createPlayer(mp3.getFilePath());
		player.realize();

		destroyPauseTimer();
		destroyStopTimer();

		setAdequateVolume();
		if (state.equals(State.NIGHT_MODE)) {
			nightModeIndex--;
		}

		if (navigator == null) {
			navigator = new Navigator(mp3);
		}

		player.prefetch();

		if (!state.equals(State.PAUSE_MP3)) {
			player.start();
			state.add(State.PLAY_MP3);
		}

		setupRestart();

		mainScreen.handleCommands();

		player.addPlayerListener(this);
		MetaDataControl metadatas = (MetaDataControl) player
				.getControl("javax.microedition.media.control.MetaDataControl");
		// title, author, album, date, genre
		MP3Metadata metadata = new MP3Metadata(currentMp3Title, metadatas
				.getKeyValue("author"));
		mainScreen.setMetadata(metadata);
		setTitleColor(mp3);
		mainScreen.repaint();
	}

	private void destroyStopTimer() {
		if (stopTimer != null) {
			stopTimer.cancel();
			stopTimer = null;
		}
	}

	private void setAdequateVolume() {
		// if (state.equals(State.NIGHT_MODE)) {
		// if (nightModeIndex < 1) {
		// alert("Time to sleep");
		// state.remove(State.NIGHT_MODE);
		// return;
		// } else {
		// alert(nightModeIndex + " tunes before sleep");
		// VolumeControl volumeControl = PlayerUtils
		// .getVolumeControl(player);
		// if (volumeControl != null) {
		// volumeControl.setLevel(PlayerUtils
		// .getVolumeValue(nightModeIndex));
		// }
		// }
		// } else {
		PlayerUtils.setMaxVolume(player);
		// }
	}

	private void setTitleColor(Mp3File mp3) {
		String rating = mp3.getRating();
		if ((rating != null) && (Mp3DBRecord.GOLD_RATING.equals(rating))) {
			state.add(State.GOLDEN_TUNE);
		} else {
			state.remove(State.GOLDEN_TUNE);
		}
	}

	private void destroyPauseTimer() {
		if (pauseTimer != null) {
			pauseTimer.cancel();
			pauseTimer = null;
		}
	}

	public static void alertException(Throwable t, Object caller, String method) {
		AlertScreen alert = new AlertScreen(t.getMessage() + " in class "
				+ caller.getClass().getName() + "." + method, "Error");
		instance.getBackScreen = Display.getDisplay(instance).getCurrent();
		Display.getDisplay(instance).setCurrent(alert);
	}

	public static void debugAlert(String message, String title) {
		AlertScreen alert = new AlertScreen(message, title);
		instance.getBackScreen = Display.getDisplay(instance).getCurrent();
		Display.getDisplay(instance).setCurrent(alert);
	}

	public void playNextMP3() throws Throwable {
		destroyPlayer();
		makePauseAndThenPlay();
	}

	private void destroyPlayer() throws MediaException {
		if (player != null) {
			player.stop();
			player.close();
			player = null;
		}
		mainScreen.handleCommands();
	}

	private void makePauseAndThenPlay() throws Throwable {

		alert("Pause", 3000);

		state.remove(State.PAUSE_MP3);
		state.remove(State.PLAY_MP3);

		destroyPauseTimer();

		pauseTimer = new Timer();
		pauseTimer.schedule(new TimerTask() {

			public void run() {
				pauseTimer = null;
				if (state.equals(State.REPEAT_ONE_TUNE)) {
					runCurrentMp3();
				} else if (state.equals(State.PLAYLIST_MODE)) {
					secureGotoNext();
					runCurrentMp3();
				} else if (state.equals(State.NO_REPEAT_NO_PLAYLIST)) {
					if (navigator.hasNext()) {
						secureGotoNext();
						runCurrentMp3();
					}
				}
			}

		}, 35 * 1000);

	}

	public void playerUpdate(Player aPlayer, String event, Object data) {
		if (PlayerListener.END_OF_MEDIA.equals(event)) {
			try {
				mainScreen.handleCommands();

				playNextMP3();
				mainScreen.repaint();
			} catch (Throwable t) {
				alertException(t, this, "playerUpdate()");
			}
			schedulePlayerStop();

		} else if (PlayerListener.DEVICE_UNAVAILABLE.equals(event)) {
			if (restartTimer != null) {
				restartTimer.cancel();
			}
			restartManager.restartPlayer(currentTime);
		}
	}

	private void schedulePlayerStop() {
		if (stopTimer != null) {
			stopTimer.cancel();
		}
		stopTimer = new Timer();
		stopTimer.schedule(new TimerTask() {

			public void run() {
				notifyDestroyed();
			}

		}, 3000 * 60);
	}

	public void alert(String message) {
		alert(message, 3000);
	}

	public void alert(String message, int timeout) {
		mainScreen.alert(message, timeout);
	}

	public void keyPressed(int keyCode) {

		Mp3File mp3 = null;

		if (keyCode == KeyCode.NINE) {
			// RamPerfo.displayCurrent();
			Log.display();
		} else if (keyCode == KeyCode.HAUT) {
			getToArtistSearch();
		} else if (keyCode == KeyCode.BAS) {
			TitleSearchScreen newTitleSearchScreen = new TitleSearchScreen();
			setDisplay(newTitleSearchScreen);
		}

		/*
		 * if (!state.equals(State.PLAYLISTS_READY)) { alert("Not ready yet",
		 * 1000); return; }
		 */
		if (keyCode == KeyCode.ASTERISK) {
			OptionScreen1 opts = new OptionScreen1();
			setDisplay(opts);
			return;
		}

		if (keyCode == KeyCode.DIESE) {
			setDisplay(suggestScreen);
		}

		if (keyCode == KeyCode.GAUCHE) {
			if (!state.equals(State.REPEAT_ONE_TUNE)) {
				secureGotoPrevious();
				runCurrentMp3();
			} else if (navigator == null) {
				mp3 = getRandomMP3();
			}
		} else if (keyCode == KeyCode.DROITE) {
			if (!state.equals(State.REPEAT_ONE_TUNE)) {
				secureGotoNext();
				runCurrentMp3();
			} else if (navigator == null) {
				mp3 = getRandomMP3();
			}
		}

		state.remove(State.ANY_MODE);

		if (keyCode == KeyCode.ONE) {
			wickedKeyPressed();
//			setDisplay(new TestKeyboardScreen());
		} else if (keyCode == KeyCode.ABC) {
			currentPlaylist = (DBPlaylist) playlists.get(Genres.CALME);
			mp3 = getRandomMP3();
		} else if (keyCode == KeyCode.DEF) {
			currentPlaylist = (DBPlaylist) playlists.get(Genres.ENERGIE);
			mp3 = getRandomMP3();
		} else if (keyCode == KeyCode.GHI) {
			currentPlaylist = (DBPlaylist) playlists.get(Genres.GOOD);
			mp3 = getRandomMP3();
		} else if (keyCode == KeyCode.JKL) {
			state.add(State.ANY_MODE);
			mp3 = getRandomMP3();
		} else if (keyCode == KeyCode.MNO) {
			currentPlaylist = nowPlaylist;
			mp3 = getRandomMP3();
		} else if (keyCode == KeyCode.PQRS) {
			if (state.equals(State.WICKED_KEY_PRESSED)) {
				currentPlaylist = (DBPlaylist) playlists.get(Genres.POUBELLE);
				mp3 = getRandomMP3();
			}
		} else if (keyCode == KeyCode.TUV) {
			currentPlaylist = (DBPlaylist) playlists.get(Genres.HIP_HOP);
			mp3 = getRandomMP3();
		} else if (keyCode == KeyCode.ZERO) {

			try {

				if ((navigator != null)
						&& (isLink(navigator.getCurrentMp3File()))) {
					setDisplay(new DeleteNewScreen(navigator
							.getCurrentMp3File()));
				} else {
					alert("Cannot delete", 1000);
					TimePerfo.displayCurrent();
				}

			} catch (EmptyNavigatorException e) {
				// do nothing
				alertException(e, this, "startApp()");
			}
		} else if (keyCode == KeyCode.ONE) {
			// setDisplay(new SuggestScreen());
		}

		if (mp3 != null) {
			secureSetCurrent(mp3);
			showCurrentMode();
			runCurrentMp3();
		}

	}

	private boolean isLink(Mp3File currentMp3File) {
		// TODO URGENT isLink
		return true;
	}

	public void getToArtistSearch() {
		state.remove(State.MODE_SEARCH_BY_TITLE);
		state.add(State.MODE_SEARCH_BY_ARTIST);
		artistSearchScreen.reboot();
		setDisplay(artistSearchScreen);
	}

	public static void wickedKeyPressed() {
		if (instance.state.equals(State.WICKED_KEY_PRESSED)) {
			instance.state.remove(State.WICKED_KEY_PRESSED);
		} else {
			instance.state.add(State.WICKED_KEY_PRESSED);
		}
	}

	private void secureGotoNext() {
		Mp3File randomMp3 = null;
		try {
			randomMp3 = getRandomMP3();
		} catch (Throwable e) {
			alertException(e, this, "secureGotoNext()");
		}

		if (navigator == null) {
			navigator = new Navigator(randomMp3);
			// alert("Random tune selected", 1000);
		} else if (!navigator.hasNext()) {
			navigator.setCurrent(randomMp3);
			// alert("Random tune selected", 1000);
		} else {
			navigator.gotoNext();
		}
	}

	private void secureGotoPrevious() {
		try {
			if ((navigator != null) && (navigator.getPrevious() != null)) {
				navigator.gotoPrevious();
			}
		} catch (EmptyNavigatorException e) {
			alertException(e, this, "startApp()");
		}

	}

	private void showCurrentMode() {
		/*
		 * Temporary simplification if (state.equals(State.ANY_MODE)) {
		 * alert("Mode Any", 1000); } else if ((navigator != null) &&
		 * (navigator.getCurrent() != null)) { String dir =
		 * navigator.getCurrent().getDir(); String mode = ((Playlist)
		 * playlists.get(dir)).getType(); alert("Mode " + mode, 1000); }
		 */
	}

	public static Boot getInstance() {
		return instance;
	}

	public State getState() {
		return state;
	}

	// TODO User feedback : enqueued
	public void enqueueMp3(Mp3File mp3) {
		mainScreen.handleCommands();

		if (noMp3Running()) {
			try {
				secureSetCurrent(mp3);
				runCurrentMp3();
			} catch (Throwable t) {
				alertException(t, this, "searchChoiceCompleted()");
			}
		} else if (state.equals(State.REPEAT_ONE_TUNE)) {
			navigator = new Navigator(mp3);
			runCurrentMp3();
		} else {
			navigator.setLast(mp3);
		}

		mainScreen.alert("Tune added to playlist", 1000);
	}

	private void runCurrentMp3() {
		try {
			if ((navigator != null) && (navigator.getCurrentMp3File() != null)) {
				runMP3(navigator.getCurrentMp3File());
			}
		} catch (EmptyNavigatorException e) {
			alertException(e, this, "runCurrentMp3()");
		} catch (MediaException e) {
			alertException(new Exception("Error in media."), this, "runCurrentMp3()");
		} catch (IOException e) {
			alertException(new Exception("I/O exception"), this, "runCurrentMp3()");
		}
	}

	private void secureSetCurrent(Mp3File mp3) {
		if ((navigator == null) || state.equals(State.REPEAT_ONE_TUNE)) {
			navigator = new Navigator(mp3);
		} else {
			navigator.setCurrent(mp3);
		}
	}

	private boolean noMp3Running() {
		return ((!state.equals(State.PAUSE_MP3)) && (!state
				.equals(State.PLAY_MP3)));
	}

	public static State state() {
		return instance.getState();
	}

	public static void removeState(State aState) {
		instance.getState().remove(aState);
	}

	public static void addState(State aState) {
		instance.getState().add(aState);
	}

	public static void repaint() {
		instance.mainScreen.repaint();
		instance.mainScreen.handleCommands();
	}

	public static void resetNightModeIndex() {
		instance.nightModeIndex = 5;
	}

	public static void switchToNewList() {
		setDisplay(instance.newListScreen);
	}

	public void cancelNewList() {
		setDisplay(instance.mainScreen);
	}

	public void pausePlayer() {

		try {
			player.stop();
			state.add(State.PAUSE_MP3);
			mainScreen.handleCommands();
		} catch (MediaException e) {
			alertException(e, this, "pausePlayer()");
		}

		state.remove(State.PLAY_MP3);
		mainScreen.handleCommands();
		mainScreen.repaint();
	}

	public void playPlayer() {
		try {

			player.start();
			setAdequateVolume();
			state.remove(State.PAUSE_MP3);
			state.add(State.PLAY_MP3);
			mainScreen.handleCommands();
			mainScreen.repaint();

		} catch (MediaException t) {
			alertException(t, this, "playPlayer()");
		}
	}

	public void backToSearchChoice() {
		setDisplay(mainScreen);
	}

	public void popUp(Mp3File mp3) {
		PopUpNameScreen popupScreen = new PopUpNameScreen(mp3);
		setDisplay(popupScreen);
		popupScreen.setup();
	}

	public void readyToGo() {
		setDisplay(mainScreen);
	}

	public void deleteCurrentMp3() {
		try {
			player.stop();
			player.deallocate();
			FileConnectionUtils.secureDelete(navigator.getCurrentMp3File());
	
			navigator.removeCurrent();
			mainScreen.setMetadata(new MP3Metadata("", ""));
			mainScreen.repaint();

			Mp3File mp3 = NowManager.selectNewMp3FromBoot();
			navigator.setCurrent(mp3);
			Log.log("Title = " + mp3.getTitle());
			Log.log("Path = ");
			Log.log(mp3.getFilePath());
			runCurrentMp3();

			setDisplay(new DeleteReportScreen());
			readyToGo();
		} catch (Throwable e) {
			alertException(e, this, "deleteCurrentMp3()");
		}
	}

	public void showStats() {
		setDisplay(new StatsScreen());
	}

	public static void setDisplay(Canvas canvas) {
		if (instance.getBackScreen == null) {
			Display.getDisplay(instance).setCurrent(canvas);
			canvas.repaint();
		} else {
			instance.getBackScreen = canvas;
		}
	}

	public void lockScreen() {
		setDisplay(new LockScreen());
	}

	public void pawnCurrent() {
		try {
			Mp3File mp3File = navigator.getCurrentMp3File();
			if (mp3File != null) {
				try {
					Pawner.pawn(mp3File);
					alert("Pawned!", 1000);
				} catch (IOException e) {
					alertException(e, this, "pawnCurrent()");
				} catch (AlreadyPawnedException e) {
					Pawner.unpawn(mp3File);
					alert("Unpawned!", 2000);
				}
			}
			readyToGo();
			mainScreen.repaint();

		} catch (EmptyNavigatorException e) {
			alertException(new Exception("Empty navigator"), this, "startApp()");
		}
	}

	public static void showPawnList() {
		PawnScreen pawnScreen = new PawnScreen();
		setDisplay(pawnScreen);
	}

	public void showPearlList() {
		// TODO showPearlList()
	}

	public void displayRelevantScreen() {
		if (state.equals(State.MODE_SEARCH_BY_TITLE)) {
			setDisplay(mainScreen);
		} else if (state.equals(State.MODE_SEARCH_BY_ARTIST)) {
			setDisplay(artistSearchScreen);
		}
	}

	public void restart(long time) throws MediaException {
		try {
			player = Manager.createPlayer(navigator.getCurrentMp3File()
					.getFilePath());
		} catch (IOException e) {
			debugErrorAlert(e.getClass().getName());
		} catch (EmptyNavigatorException e) {
			alertException(new Exception("Empty navigator."), this, "restart()");
		}
		player.realize();
		player.prefetch();
		player.setMediaTime(time);
		player.start();

		setAdequateVolume();
		player.addPlayerListener(this);

		setupRestart();
		destroyStopTimer();
	}

	private void setupRestart() {
		restartTimer = new Timer();
		restartTimer.schedule(new RestartTask(), 1000, 1000);
	}

	private class RestartTask extends TimerTask {

		public void run() {
			long candidate = player.getMediaTime();

			if (candidate > 0) {
				currentTime = candidate;
			}
		}

	}

	public void showEvaluation() {
		try {
			if ((navigator != null) && (navigator.getCurrentMp3File() != null)) {
				EvaluationScreen evalScreen = new EvaluationScreen(navigator
						.getCurrentMp3File());
				setDisplay(evalScreen);
			}
		} catch (EmptyNavigatorException e) {
			alertException(e, this, "showEvaluation()");
		}
	}

	public static void main(String[] args) {
		// Created only for code analysis
		try {
			new Boot().startApp();
		} catch (MIDletStateChangeException e) {
			e.printStackTrace();
		}
	}

	public void showSequentialEvaluation() {
		EvaluationManager evalManager = new EvaluationManager();
		evalManager.startEvaluation();
	}

	public static void queueAndPlay(Mp3File mp3) {
		instance.secureSetCurrent(mp3);
		instance.runCurrentMp3();
	}

	public static void reload() {
		instance.navigator = new Navigator(true);
		instance.runCurrentMp3();
	}

	public void playCurrentFromStart() {
		try {
			restart(0);
		} catch (MediaException e) {
			alertException(e, this, "playCurrentFromStart()");
		}
		setAdequateVolume();
		state.remove(State.PAUSE_MP3);
		state.add(State.PLAY_MP3);
		mainScreen.handleCommands();
		mainScreen.repaint();
	}

	public static void displayGetBackScreen() {
		Display.getDisplay(instance).setCurrent(instance.getBackScreen);
		instance.getBackScreen = null;
	}

	public void showGenresSuggestions() {
		genreSuggestionScreen = new GenresSuggestionsScreen();
		setDisplay(genreSuggestionScreen);
	}

	public static void savePlayslist(String name) {
		if (instance.navigator == null) {
			instance.alert("No playlist to save.");
		} else {
			instance.navigator.savePlaylist(name);
			instance.alert("Playlist saved.");
		}
	}

	public static void playPlaylist(String name) {

		try {

			if (instance.navigator == null) {
				instance.navigator = new Navigator(false);
			}
			Log.log("Playlist name = " + name);
			instance.navigator.loadPlaylist(name);
			instance.runCurrentMp3();
			instance.readyToGo();

		} catch (Throwable e) {
			alertException(e, new Boot(), "playPlaylist()");
		}
	}

	public static void debugErrorAlert(String message) {
		debugAlert(message, "Error");
	}

	public static void showShaker() {
		setDisplay(new ShakerScreen());
	}
}
